<template>
  <div class="chat-container">
    <!-- 聊天头部 -->
    <div class="chat-header">
      <div class="header-left">
        <h3 class="chat-title">
          <i class="el-icon-chat-dot-round"></i>
          办公群聊
        </h3>
        <span class="online-status" :class="{ online: isConnected }">
          {{ isConnected ? "在线" : "离线" }}
        </span>
        <span class="online-count" v-if="isConnected">
          ({{ uniqueOnlineUserCount }}人在线)
        </span>
      </div>
      <div class="header-right">
        <el-button
          type="info"
          size="small"
          icon="el-icon-user"
          @click="showOnlineUsers = !showOnlineUsers"
        >
          在线用户
        </el-button>
        <el-button
          type="danger"
          size="small"
          icon="el-icon-delete"
          @click="clearChat"
          :disabled="messages.length === 0"
        >
          清空聊天
        </el-button>
        <el-button
          :type="isConnected ? 'warning' : 'success'"
          size="small"
          :icon="isConnected ? 'el-icon-close' : 'el-icon-connection'"
          @click="toggleConnection"
        >
          {{ isConnected ? "断开连接" : "连接" }}
        </el-button>
      </div>
    </div>

    <!-- 聊天主体 -->
    <div class="chat-main">
      <!-- 在线用户侧边栏 -->
      <div class="online-users-sidebar" v-if="showOnlineUsers">
        <div class="sidebar-header">
          <h4>在线用户 ({{ uniqueOnlineUserCount }})</h4>
          <el-button
            type="text"
            icon="el-icon-close"
            @click="showOnlineUsers = false"
          />
        </div>
        <div class="user-list">
          <div
            v-for="(userInfo, sessionId) in uniqueOnlineUsers"
            :key="sessionId"
            class="user-item"
            @click="showUserInfo(userInfo)"
          >
            <div class="avatar-container">
              <img
                :src="userInfo.avatar || defaultAvatar"
                :alt="userInfo.username"
                class="user-avatar"
                @error="handleAvatarError"
              />
              <div class="online-indicator"></div>
            </div>
            <div class="user-info">
              <span class="username">{{ userInfo.username }}</span>
              <span
                class="nickname"
                v-if="
                  userInfo.nickname && userInfo.nickname !== userInfo.username
                "
              >
                ({{ userInfo.nickname }})
              </span>
              <span class="last-active" v-if="userInfo.joinTime">
                活跃于 {{ formatTime(userInfo.joinTime) }}
              </span>
            </div>
          </div>
          <div
            v-if="Object.keys(uniqueOnlineUsers).length === 0"
            class="no-users"
          >
            暂无在线用户
          </div>
        </div>
      </div>

      <!-- 消息列表 -->
      <div class="message-list" ref="messageList">
        <div
          v-for="(message, index) in messages"
          :key="index"
          class="message-item"
          :class="{
            'message-user': message.type === 'user',
            'message-system': message.type === 'system',
          }"
        >
          <!-- 用户消息 -->
          <div
            v-if="message.type === 'user'"
            class="message-content user-message"
          >
            <div class="message-bubble">
              <div class="message-info">
                <span class="username">{{ message.username }}</span>
                <span class="time">{{ formatTime(message.timestamp) }}</span>
              </div>
              <div class="message-text">{{ message.content }}</div>
            </div>
            <div class="avatar">
              <div class="avatar-container">
                <img
                  :src="message.avatar || defaultAvatar"
                  :alt="message.username"
                  @error="handleAvatarError"
                />
                <div class="online-indicator"></div>
              </div>
            </div>
          </div>

          <!-- 系统消息 -->
          <div
            v-else-if="message.type === 'system'"
            class="message-content system-message"
          >
            <div class="system-bubble">
              <i class="el-icon-bell"></i>
              <span>{{ message.content }}</span>
              <span class="time">{{ formatTime(message.timestamp) }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="input-area">
        <div class="input-container">
          <el-input
            v-model="inputMessage"
            type="textarea"
            :rows="3"
            placeholder="输入消息内容..."
            @keydown.ctrl.enter="sendMessage"
            :disabled="!isConnected"
            resize="none"
          />
          <div class="input-actions">
            <div class="input-left">
              <el-button
                type="text"
                size="small"
                @click="showSystemMessageDialog = true"
                v-if="isAdmin"
              >
                发送系统消息
              </el-button>
            </div>
            <el-button
              type="primary"
              icon="el-icon-s-promotion"
              @click="sendMessage"
              :disabled="!inputMessage.trim() || !isConnected"
            >
              发送
            </el-button>
          </div>
        </div>
      </div>
    </div>

    <!-- AI助手侧边栏 -->
    <div class="ai-assistant-sidebar" :class="{ show: aiAssistantOpen }">
      <div class="ai-sidebar-header">
        <div class="ai-header-info">
          <img src="@/assets/ai-avatar.png" alt="AI助手" class="ai-avatar" />
          <div class="ai-info">
            <h4>AI助手</h4>
            <span class="ai-status" :class="{ online: aiConnected }">
              {{ aiConnected ? "在线" : "离线" }}
            </span>
          </div>
        </div>
        <!-- 新增：模型选择框 -->
        <el-select
          v-model="selectedModel"
          size="small"
          style="width: 140px; margin-left: 10px"
        >
          <el-option label="硅基流动AI" value="liudong"></el-option>
          <el-option label="ollma" value="ollma"></el-option>
        </el-select>
        <div class="ai-header-actions">
          <el-button
            type="text"
            icon="el-icon-delete"
            @click="clearAIChat"
            :disabled="aiMessages.length === 0"
            class="clear-btn"
            title="清空聊天记录"
          />
          <el-button
            type="text"
            icon="el-icon-close"
            @click="aiAssistantOpen = false"
            class="close-btn"
          />
        </div>
      </div>

      <div class="ai-chat-area">
        <div class="ai-messages" ref="aiMessageList">
          <div
            v-for="(message, index) in aiMessages"
            :key="index"
            class="ai-message-item"
            :class="{
              'ai-message': message.type === 'ai',
              'user-message': message.type === 'user',
            }"
          >
            <div v-if="message.type === 'ai'" class="ai-message-content">
              <div class="ai-avatar-small">
                <img src="@/assets/ai-avatar.png" alt="AI" />
              </div>
              <div class="ai-message-bubble">
                <div
                  class="ai-message-text"
                  v-html="formatMessage(message.content)"
                ></div>
                <div class="ai-message-time">
                  {{ formatTime(message.timestamp) }}
                </div>
              </div>
            </div>
            <div v-else class="user-message-content">
              <div class="user-message-bubble">
                <div class="user-message-text">{{ message.content }}</div>
                <div class="user-message-time">
                  {{ formatTime(message.timestamp) }}
                </div>
              </div>
              <div class="user-avatar-small">
                <div class="avatar-container">
                  <img
                    :src="avatar || defaultAvatar"
                    :alt="nickName || name"
                    @error="handleAvatarError"
                  />
                  <div class="online-indicator"></div>
                </div>
              </div>
            </div>
          </div>

          <!-- AI加载状态 -->
          <div v-if="aiLoading" class="ai-message-item">
            <div class="ai-message-content">
              <div class="ai-avatar-small">
                <img src="@/assets/ai-avatar.png" alt="AI" />
              </div>
              <div class="ai-message-bubble">
                <div class="ai-message-text">
                  <div class="typing-indicator">
                    <span></span>
                    <span></span>
                    <span></span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="ai-input-area">
          <el-input
            v-model="aiInputMessage"
            type="textarea"
            :rows="2"
            placeholder="向AI助手提问..."
            @keydown.ctrl.enter="sendAIMessage"
            :disabled="!aiConnected"
            resize="none"
          />
          <div class="ai-input-actions">
            <el-button
              type="primary"
              size="small"
              icon="el-icon-s-promotion"
              @click="sendAIMessage"
              :disabled="!aiInputMessage.trim() || !aiConnected || aiLoading"
              :loading="aiLoading"
            >
              发送
            </el-button>
          </div>
        </div>
      </div>
    </div>

    <!-- AI助手触发按钮 -->
    <div class="ai-trigger-btn" @click="aiAssistantOpen = true">
      <i class="el-icon-s-help"></i>
      <span>AI助手</span>
    </div>

    <!-- 系统消息对话框 -->
    <el-dialog
      title="发送系统消息"
      :visible.sync="showSystemMessageDialog"
      width="500px"
    >
      <el-form :model="systemMessageForm" label-width="80px">
        <el-form-item label="消息内容">
          <el-input
            v-model="systemMessageForm.content"
            type="textarea"
            :rows="4"
            placeholder="请输入系统消息内容..."
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showSystemMessageDialog = false">取消</el-button>
        <el-button type="primary" @click="sendSystemMessage">发送</el-button>
      </div>
    </el-dialog>

    <!-- 用户信息对话框 -->
    <el-dialog
      title="用户信息"
      :visible.sync="showUserInfoDialog"
      width="400px"
      center
      append-to-body
    >
      <div class="user-info-dialog" v-if="selectedUser">
        <div class="user-avatar-large">
          <img
            :src="selectedUser.avatar || defaultAvatar"
            :alt="selectedUser.username"
            @error="handleAvatarError"
          />
          <div class="online-indicator-large"></div>
        </div>
        <div class="user-details">
          <h3 class="user-name">{{ selectedUser.username }}</h3>
          <p
            class="user-nickname"
            v-if="
              selectedUser.nickname &&
              selectedUser.nickname !== selectedUser.username
            "
          >
            {{ selectedUser.nickname }}
          </p>
          <p class="user-status">
            <i class="el-icon-success"></i>
            在线
          </p>
          <p class="user-join-time" v-if="selectedUser.joinTime">
            加入时间：{{ formatTime(selectedUser.joinTime) }}
          </p>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showUserInfoDialog = false">关闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
import { getCompletion } from "@/api/ai";
import { generateAnswer } from "@/api/ollama";
import {
  getOnlineUserCount,
  getOnlineUsers,
  sendSystemMessage as sendSystemMsg,
  clearChatHistory as clearChatHistoryApi,
  getAIInfo,
} from "@/api/chat";
import SockJS from "sockjs-client";

export default {
  name: "PeopleChat",
  data() {
    return {
      // WebSocket连接
      websocket: null,
      isConnected: false,
      userDisconnected: false, // 用户主动断开标志

      // 消息相关
      messages: [],
      inputMessage: "",

      // 在线用户相关
      onlineUserCount: 0,
      onlineUsers: {},
      showOnlineUsers: false,

      // 系统消息相关
      showSystemMessageDialog: false,
      systemMessageForm: {
        content: "",
      },

      // 默认头像
      defaultAvatar: require("@/assets/images/profile.jpg"),

      // AI模型配置
      aiModel: "deepseek-r1:1.5b",
      selectedModel: "liudong", // 新增，默认选硅基流动AI

      // 定时器
      statisticsTimer: null,

      // 重连相关
      reconnectAttempts: 0,
      maxReconnectAttempts: 5,
      reconnectInterval: 3000,
      reconnectTimer: null,

      // AI助手相关
      aiConnected: false,
      aiMessages: [],
      aiInputMessage: "",
      aiLoading: false,

      // 用户信息相关
      showUserInfoDialog: false,
      selectedUser: null,
    };
  },

  computed: {
    ...mapGetters(["name", "avatar", "nickName", "roles"]),

    // 判断是否为管理员
    isAdmin() {
      return this.roles && this.roles.includes("admin");
    },

    // 监听AI助手状态
    aiAssistantOpen: {
      get() {
        return this.$store.state.app.aiAssistantOpen;
      },
      set(value) {
        this.$store.dispatch("app/setAiAssistantOpen", value);
      },
    },

    // 去重后的在线用户列表
    uniqueOnlineUsers() {
      const uniqueUsers = {};
      const usernameCount = {};

      // 统计每个用户名的出现次数
      Object.values(this.onlineUsers).forEach((userInfo) => {
        const username = userInfo.username;
        usernameCount[username] = (usernameCount[username] || 0) + 1;
      });

      // 为每个用户名生成唯一的key
      Object.entries(this.onlineUsers).forEach(([sessionId, userInfo]) => {
        const username = userInfo.username;
        const nickname = userInfo.nickname;
        const avatar = userInfo.avatar;

        if (usernameCount[username] === 1) {
          // 如果用户名只出现一次，直接使用sessionId
          uniqueUsers[sessionId] = {
            username,
            nickname,
            avatar,
          };
        } else {
          // 如果用户名出现多次，使用用户名作为key
          uniqueUsers[username] = {
            username,
            nickname,
            avatar,
          };
        }
      });

      return uniqueUsers;
    },

    // 去重后的在线用户数量
    uniqueOnlineUserCount() {
      return Object.keys(this.uniqueOnlineUsers).length;
    },
  },

  mounted() {
    this.initWebSocket();
    this.addWelcomeMessage();
    this.startStatisticsTimer();
    this.initAIAssistant();
  },

  beforeDestroy() {
    this.closeWebSocket();
    this.stopStatisticsTimer();

    // 清理重连定时器
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  },

  methods: {
    // 初始化AI助手
    initAIAssistant() {
      this.aiConnected = true;
      this.addAIWelcomeMessage();
    },

    // 初始化WebSocket连接
    initWebSocket() {
      try {
        // 如果已经有连接，先关闭
        if (this.websocket) {
          this.websocket.close();
          this.websocket = null;
        }

        // 构建WebSocket URL
        // 开发环境使用代理，生产环境使用完整URL
        let wsUrl;
        if (process.env.NODE_ENV === "development") {
          // 开发环境：使用相对路径，通过代理转发
          wsUrl = "/dev-api/ws/chat";
        } else {
          // 生产环境：使用完整URL
          const baseUrl =
            process.env.VUE_APP_BASE_API || "http://localhost:8000";
          wsUrl = `${baseUrl}/ws/chat`;
        }

        this.websocket = new SockJS(wsUrl);

        this.websocket.onopen = () => {
          this.isConnected = true;
          this.userDisconnected = false; // 重置用户断开标志
          this.reconnectAttempts = 0; // 重置重连次数
          this.$message.success("WebSocket连接成功");

          // 发送用户加入消息
          this.sendJoinMessage();

          // 本地立即添加系统消息

          // 获取在线用户信息
          this.loadOnlineUsers();
        };

        this.websocket.onmessage = (event) => {
          try {
            const data = JSON.parse(event.data);
            this.handleWebSocketMessage(data);
          } catch (error) {
            this.$message.error("解析WebSocket消息失败");
          }
        };

        this.websocket.onclose = (event) => {
          this.isConnected = false;
          // 只有在非用户主动断开时才尝试重连
          if (!this.userDisconnected) {
            this.attemptReconnect();
          }
        };

        this.websocket.onerror = (error) => {
          this.isConnected = false;
          this.$message.error("WebSocket连接错误");
        };
      } catch (error) {
        this.$message.error("初始化WebSocket失败");

        // 尝试重连
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
          this.reconnectAttempts++;
          setTimeout(() => {
            this.initWebSocket();
          }, 3000);
        }
      }
    },

    // 安排重连
    scheduleReconnect() {
      this.reconnectAttempts++;

      this.reconnectTimer = setTimeout(() => {
        this.initWebSocket();
      }, this.reconnectInterval);
    },

    // 处理WebSocket消息
    handleWebSocketMessage(data) {
      switch (data.type) {
        case "chat":
          this.addMessage({
            type: "user",
            username: data.username,
            avatar: data.avatar,
            content: data.content,
            timestamp: data.timestamp,
          });
          break;
        case "join":
          this.addSystemMessage(`${data.username} 加入了群聊`);
          this.loadOnlineUsers();
          break;
        case "leave":
          this.addSystemMessage(`${data.username} 离开了群聊`);
          this.loadOnlineUsers();
          break;
        case "system":
          this.addMessage({
            type: "system",
            content: data.content,
            timestamp: data.timestamp,
          });
          break;
        default:
        // 未知消息类型
      }
    },

    // 发送加入消息
    sendJoinMessage() {
      if (this.websocket && this.isConnected) {
        this.websocket.send(
          JSON.stringify({
            type: "join",
            username: this.nickName || this.name,
            nickname: this.nickName,
            avatar: this.avatar,
          })
        );
      }
    },

    // 发送消息
    async sendMessage() {
      if (!this.inputMessage.trim() || !this.isConnected) return;

      const message = {
        type: "chat",
        username: this.nickName || this.name,
        nickname: this.nickName,
        avatar: this.avatar,
        content: this.inputMessage.trim(),
        timestamp: Date.now(),
      };

      // 发送到WebSocket
      if (this.websocket && this.isConnected) {
        this.websocket.send(JSON.stringify(message));
      }

      // 添加到本地消息列表
      this.addMessage(message);

      // 清空输入框
      this.inputMessage = "";
    },

    // AI助手相关方法
    async sendAIMessage() {
      if (!this.aiInputMessage.trim() || !this.aiConnected) return;

      const message = {
        type: "user",
        username: this.nickName || this.name,
        avatar: this.avatar,
        content: this.aiInputMessage.trim(),
        timestamp: Date.now(),
      };

      // 添加到AI消息列表
      this.addAIMessage(message);

      // 清空输入框
      this.aiInputMessage = "";

      // 根据模型选择调用不同API
      if (this.selectedModel === "ollma") {
        await this.generateOllmaResponse(message.content, message.username);
      } else {
        await this.generateAIResponse(message.content, message.username);
      }
    },

    // 生成AI回复
    async generateAIResponse(userMessage, username) {
      this.aiLoading = true;
      // 增加AI调用计数（与智能助手一致）
      if (this.$store && this.$store.dispatch) {
        this.$store.dispatch("ai/incrementAiCallCount");
      }
      let settled = false;
      const timeoutPromise = new Promise((_, reject) =>
        setTimeout(() => reject(new Error("timeout")), 30000)
      );
      try {
        const response = await Promise.race([
          (async () => {
            try {
              const resp = await getCompletion({
                model: "Qwen/Qwen2.5-7B-Instruct",
                message: userMessage,
              });
              if (!settled) {
                settled = true;
                return { type: "ai", resp };
              }
            } catch (e) {
              if (!settled) {
                settled = true;
                throw e;
              }
            }
          })(),
          (async () => {
            try {
              await timeoutPromise;
            } catch (e) {
              if (!settled) {
                settled = true;
                throw e;
              }
            }
          })(),
        ]);
        if (
          response &&
          response.type === "ai" &&
          response.resp &&
          response.resp.result &&
          response.resp.result.output &&
          typeof response.resp.result.output.content === "string"
        ) {
          const responseContent = response.resp.result.output.content.trim();
          const aiMessage = {
            type: "ai",
            content: responseContent,
            timestamp: Date.now(),
          };
          this.addAIMessage(aiMessage);
        } else {
          throw new Error("AI回复格式错误");
        }
      } catch (error) {
        let errorMsg = "";
        if (error.message === "timeout") {
          errorMsg = "AI助手正在升级中，请稍后再试~";
        } else {
          errorMsg = "AI回复失败，请重试";
        }
        this.$message.error(errorMsg);
        const errorMessage = {
          type: "ai",
          content: errorMsg,
          timestamp: Date.now(),
        };
        this.addAIMessage(errorMessage);
      } finally {
        this.aiLoading = false;
      }
    },

    // 新增：ollma模型回复
    async generateOllmaResponse(userMessage, username) {
      this.aiLoading = true;
      if (this.$store && this.$store.dispatch) {
        this.$store.dispatch("ai/incrementAiCallCount");
      }
      let settled = false;
      const timeoutPromise = new Promise((_, reject) =>
        setTimeout(() => reject(new Error("timeout")), 30000)
      );
      try {
        const response = await Promise.race([
          (async () => {
            try {
              // 只改ollma的调用，模型名默认用'qwen:7b'
              const resp = await generateAnswer(
                "deepseek-r1:1.5b",
                userMessage
              );

              if (!settled) {
                settled = true;
                return { type: "ai", resp };
              }
            } catch (e) {
              if (!settled) {
                settled = true;
                throw e;
              }
            }
          })(),
          (async () => {
            try {
              await timeoutPromise;
            } catch (e) {
              if (!settled) {
                settled = true;
                throw e;
              }
            }
          })(),
        ]);
        // 宽容处理ollma返回
        let responseContent = "";
        if (response && response.type === "ai" && response.resp) {
          // 1. 先尝试原格式
          if (
            response.resp.result &&
            response.resp.result.output &&
            typeof response.resp.result.output.content === "string"
          ) {
            responseContent = response.resp.result.output.content.trim();
          }
          // 2. ollma常见格式：直接有content字段
          else if (typeof response.resp.content === "string") {
            responseContent = response.resp.content.trim();
          }
          // 3. ollma常见格式：直接是字符串
          else if (typeof response.resp === "string") {
            responseContent = response.resp.trim();
          }
        }
        if (responseContent) {
          // 去除ollama返回中的<think>标签及其换行符
          responseContent = responseContent
            .replace(/<think>.*?<\/think>/gs, "")
            .replace(/^\s+|\s+$/g, "");
          const aiMessage = {
            type: "ai",
            content: responseContent,
            timestamp: Date.now(),
          };
          this.addAIMessage(aiMessage);
        } else {
          // 打印全部response
          throw new Error("AI回复格式错误");
        }
      } catch (error) {
        // 打印错误
        console.error("ollma error:", error);
        let errorMsg = "";
        if (error.message === "timeout") {
          errorMsg = "AI助手正在升级中，请稍后再试~";
        } else {
          errorMsg = "AI回复失败，请重试";
        }
        this.$message.error(errorMsg);
        const errorMessage = {
          type: "ai",
          content: errorMsg,
          timestamp: Date.now(),
        };
        this.addAIMessage(errorMessage);
      } finally {
        this.aiLoading = false;
      }
    },

    // 构建AI提示词
    buildAIPrompt(userMessage, username) {
      const currentTime = new Date().toLocaleString("zh-CN");
      return `你是一个专业的办公助手，专门为办公群聊提供帮助。

用户信息：
- 用户名：${username}
- 当前时间：${currentTime}

用户问题：${userMessage}

请以友好、专业、简洁的方式回答用户的问题。回答要：
1. 准确、有用
2. 语言简洁明了
3. 符合办公场景
4. 适当使用表情符号增加亲和力
5. 如果问题不明确，可以适当询问

请直接回答，不要包含"作为AI助手"等前缀。`;
    },

    // 添加AI消息
    addAIMessage(message) {
      this.aiMessages.push(message);
      this.$nextTick(() => {
        this.scrollToAIBottom();
      });
    },

    // 添加AI欢迎消息
    addAIWelcomeMessage() {
      this.addAIMessage({
        type: "ai",
        content: `您好！我是您的AI助手，可以帮您解答问题、提供建议。有什么需要帮助的吗？`,
        timestamp: Date.now(),
      });
    },

    // 滚动到AI消息底部
    scrollToAIBottom() {
      const aiMessageList = this.$refs.aiMessageList;
      if (aiMessageList) {
        aiMessageList.scrollTop = aiMessageList.scrollHeight;
      }
    },

    // 加载在线用户信息
    async loadOnlineUsers() {
      try {
        const [countRes, usersRes] = await Promise.all([
          getOnlineUserCount(),
          getOnlineUsers(),
        ]);

        if (countRes.code === 200) {
          this.onlineUserCount = countRes.data;
        }

        if (usersRes.code === 200) {
          this.onlineUsers = usersRes.data;
        }
      } catch (error) {
        this.$message.error("加载在线用户信息失败");
      }
    },

    // 发送系统消息
    async sendSystemMessage() {
      if (!this.systemMessageForm.content.trim()) {
        this.$message.warning("请输入系统消息内容");
        return;
      }

      try {
        const res = await sendSystemMsg({
          content: this.systemMessageForm.content.trim(),
        });

        if (res.code === 200) {
          this.$message.success("系统消息发送成功");
          this.showSystemMessageDialog = false;
          this.systemMessageForm.content = "";
        } else {
          this.$message.error(res.msg || "发送失败");
        }
      } catch (error) {
        this.$message.error("发送系统消息失败");
      }
    },

    // 添加消息
    addMessage(message) {
      this.messages.push(message);
      this.$nextTick(() => {
        this.scrollToBottom();
      });
    },

    // 添加系统消息
    addSystemMessage(content) {
      this.addMessage({
        type: "system",
        content,
        timestamp: Date.now(),
      });
    },

    // 添加欢迎消息
    addWelcomeMessage() {
      this.addMessage({
        type: "system",
        content: `欢迎来到办公群聊！您可以与在线用户进行交流，也可以点击右下角的AI助手按钮获取帮助。`,
        timestamp: Date.now(),
      });
    },

    // 清空聊天记录
    async clearChat() {
      try {
        await this.$confirm("确定要清空所有聊天记录吗？", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        });

        const res = await clearChatHistoryApi();
        if (res.code === 200) {
          this.messages = [];
          this.addWelcomeMessage();
          this.$message.success("聊天记录已清空");
        } else {
          this.$message.error(res.msg || "清空失败");
        }
      } catch (error) {
        if (error !== "cancel") {
          this.$message.error("清空聊天记录失败");
        }
      }
    },

    // 切换连接状态
    toggleConnection() {
      if (this.isConnected) {
        this.closeWebSocket();
      } else {
        this.initWebSocket();
      }
    },

    // 关闭WebSocket连接
    closeWebSocket() {
      // 设置用户主动断开标志
      this.userDisconnected = true;

      // 断开前通知后端自己离开
      if (this.websocket && this.isConnected) {
        this.websocket.send(
          JSON.stringify({
            type: "leave",
            username: this.nickName || this.name,
            nickname: this.nickName,
            avatar: this.avatar,
          })
        );
        // 本地立即添加系统消息
        this.addSystemMessage(`${this.nickName || this.name} 离开了群聊`);
      }

      // 清理重连定时器
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = null;
      }

      if (this.websocket) {
        this.websocket.close(1000, "用户主动断开连接");
        this.websocket = null;
      }
      // 主动刷新在线用户列表
      this.loadOnlineUsers();
    },

    // 滚动到底部
    scrollToBottom() {
      const messageList = this.$refs.messageList;
      if (messageList) {
        messageList.scrollTop = messageList.scrollHeight;
      }
    },

    // 格式化时间
    formatTime(timestamp) {
      const date = new Date(timestamp);
      const now = new Date();
      const diff = now - date;

      if (diff < 60000) {
        // 1分钟内
        return "刚刚";
      } else if (diff < 3600000) {
        // 1小时内
        return `${Math.floor(diff / 60000)}分钟前`;
      } else if (date.toDateString() === now.toDateString()) {
        // 今天
        return date.toLocaleTimeString("zh-CN", {
          hour: "2-digit",
          minute: "2-digit",
        });
      } else {
        return (
          date.toLocaleDateString("zh-CN") +
          " " +
          date.toLocaleTimeString("zh-CN", {
            hour: "2-digit",
            minute: "2-digit",
          })
        );
      }
    },

    // 格式化消息内容
    formatMessage(content) {
      // 简单的markdown格式化
      return content
        .replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
        .replace(/\*(.*?)\*/g, "<em>$1</em>")
        .replace(/`(.*?)`/g, "<code>$1</code>")
        .replace(/\n/g, "<br>");
    },

    // 获取用户头像
    getUserAvatar(username) {
      // 这里可以根据用户名获取对应的头像
      // 暂时返回默认头像
      return this.defaultAvatar;
    },

    // 开始统计定时器
    startStatisticsTimer() {
      this.statisticsTimer = setInterval(() => {
        if (this.isConnected) {
          this.loadOnlineUsers();
        }
      }, 30000); // 每30秒更新一次
    },

    // 停止统计定时器
    stopStatisticsTimer() {
      if (this.statisticsTimer) {
        clearInterval(this.statisticsTimer);
        this.statisticsTimer = null;
      }
    },

    // 尝试重连
    attemptReconnect() {
      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        this.reconnectAttempts++;
        setTimeout(() => {
          this.initWebSocket();
        }, 3000);
      } else {
        this.$message.warning("WebSocket连接已断开");
      }
    },

    // 切换AI助手状态
    toggleAIAssistant() {
      this.aiAssistantOpen = !this.aiAssistantOpen;
    },

    // 清空AI助手聊天记录
    clearAIChat() {
      this.$confirm("确定要清空AI助手的聊天记录吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.aiMessages = [];
          this.aiInputMessage = "";
          this.addAIWelcomeMessage(); // 重新添加欢迎消息
          this.$message.success("AI助手聊天记录已清空");
        })
        .catch(() => {
          // 用户取消操作
        });
    },

    // 处理头像加载失败
    handleAvatarError(event) {
      // 设置默认头像
      event.target.src = this.defaultAvatar;
    },

    // 显示用户详细信息
    showUserInfo(userInfo) {
      this.selectedUser = userInfo;
      this.showUserInfoDialog = true;
    },
  },
};
</script>

<style lang="scss" scoped>
.chat-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f7fa;
}

.chat-header {
  background: #fff;
  border-bottom: 1px solid #e4e7ed;
  padding: 16px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

  .header-left {
    display: flex;
    align-items: center;
    gap: 12px;

    .chat-title {
      margin: 0;
      font-size: 18px;
      font-weight: 600;
      color: #303133;
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .online-status {
      padding: 4px 8px;
      border-radius: 12px;
      font-size: 12px;
      background: #f56c6c;
      color: #fff;

      &.online {
        background: #67c23a;
      }
    }

    .online-count {
      font-size: 12px;
      color: #909399;
    }
  }

  .header-right {
    display: flex;
    gap: 8px;
  }
}

.chat-main {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.online-users-sidebar {
  width: 250px;
  background: #fff;
  border-right: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;

  .sidebar-header {
    padding: 16px;
    border-bottom: 1px solid #e4e7ed;
    display: flex;
    justify-content: space-between;
    align-items: center;

    h4 {
      margin: 0;
      font-size: 14px;
      color: #303133;
    }
  }

  .user-list {
    flex: 1;
    padding: 12px;
    overflow-y: auto;

    .user-item {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 12px;
      border-radius: 8px;
      margin-bottom: 8px;
      transition: all 0.2s ease;
      cursor: pointer;

      &:hover {
        background: #f5f7fa;
        transform: translateY(-1px);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      }

      &:active {
        transform: translateY(0);
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
      }

      .avatar-container {
        position: relative;

        .user-avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          border: 2px solid #67c23a;
          flex-shrink: 0;
          object-fit: cover;
          background: #f0f0f0;
        }

        .online-indicator {
          position: absolute;
          top: 2px;
          right: 2px;
          width: 10px;
          height: 10px;
          border-radius: 50%;
          background: #67c23a;
          border: 2px solid #fff;
        }
      }

      .user-info {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 4px;

        .username {
          font-size: 14px;
          color: #303133;
          font-weight: 600;
          line-height: 1.2;
        }

        .nickname {
          font-size: 12px;
          color: #909399;
          line-height: 1.2;
        }

        .last-active {
          font-size: 12px;
          color: #909399;
        }
      }
    }

    .no-users {
      text-align: center;
      color: #909399;
      font-size: 14px;
      padding: 40px 20px;
    }
  }
}

.message-list {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background: #fff;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: #f1f1f1;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
  }
}

.message-item {
  margin-bottom: 20px;

  .message-content {
    display: flex;
    align-items: flex-start;
    gap: 12px;

    &.user-message {
      justify-content: flex-end;

      .avatar {
        .avatar-container {
          position: relative;

          img {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            border: 2px solid #67c23a;
          }

          .online-indicator {
            position: absolute;
            top: 2px;
            right: 2px;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background: #67c23a;
            border: 2px solid #fff;
          }
        }
      }
    }

    &.system-message {
      justify-content: center;

      .system-bubble {
        background: #f0f9ff;
        border: 1px solid #b3d8ff;
        padding: 8px 16px;
        border-radius: 20px;
        font-size: 12px;
        color: #409eff;
        display: flex;
        align-items: center;
        gap: 6px;

        i {
          font-size: 14px;
        }

        .time {
          color: #909399;
          margin-left: 8px;
        }
      }
    }
  }

  .message-bubble {
    max-width: 70%;

    .message-info {
      margin-bottom: 4px;
      display: flex;
      align-items: center;
      gap: 8px;

      .username {
        font-weight: 600;
        font-size: 14px;
        color: #303133;
      }

      .time {
        font-size: 12px;
        color: #909399;
      }
    }

    .message-text {
      background: #f4f4f5;
      padding: 12px 16px;
      border-radius: 12px;
      font-size: 14px;
      line-height: 1.5;
      color: #303133;
      word-wrap: break-word;

      ::v-deep {
        strong {
          font-weight: 600;
        }

        em {
          font-style: italic;
        }

        code {
          background: #e1f5fe;
          padding: 2px 4px;
          border-radius: 4px;
          font-family: "Courier New", monospace;
        }
      }
    }
  }

  &.message-user .message-bubble .message-text {
    background: #e8f5e8;
    border-left: 4px solid #67c23a;
    text-align: right;
  }

  &.message-user .message-bubble .message-info {
    justify-content: flex-end;
  }
}

.input-area {
  background: #fff;
  border-top: 1px solid #e4e7ed;
  padding: 16px 24px;
}

.input-container {
  .input-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 8px;

    .input-left {
      display: flex;
      align-items: center;
      gap: 12px;

      .tip {
        font-size: 12px;
        color: #909399;
      }
    }
  }
}

// 响应式设计
@media (max-width: 768px) {
  .chat-header {
    padding: 12px 16px;

    .chat-title {
      font-size: 16px;
    }

    .header-right {
      gap: 4px;

      .el-button {
        padding: 6px 8px;
        font-size: 12px;
      }
    }
  }

  .online-users-sidebar {
    width: 200px;

    .user-item {
      .avatar-container {
        .user-avatar {
          width: 28px;
          height: 28px;
        }
      }

      .user-info {
        .username {
          font-size: 13px;
        }

        .nickname {
          font-size: 11px;
        }
      }
    }
  }

  .message-list {
    padding: 12px;
  }

  .message-bubble {
    max-width: 85% !important;
  }

  .input-area {
    padding: 12px 16px;
  }

  .ai-assistant-sidebar {
    width: 100%;
    z-index: 2000; // 确保在移动端也显示在最上层

    .ai-sidebar-header {
      padding: 12px 16px;
      padding-top: calc(12px + 98px); // 为导航栏和TagsView留出空间

      .ai-header-info {
        .ai-avatar {
          width: 28px;
          height: 28px;
        }

        .ai-info h4 {
          font-size: 14px;
        }
      }

      .ai-header-actions {
        .clear-btn,
        .close-btn {
          font-size: 14px;
          padding: 3px;
        }
      }
    }

    .ai-chat-area {
      height: calc(100vh - 98px); // 为导航栏和TagsView留出空间

      .ai-messages {
        padding: 12px;

        .ai-message-item {
          .ai-message-content,
          .user-message-content {
            .ai-avatar-small,
            .user-avatar-small {
              width: 24px;
              height: 24px;
            }

            .ai-message-bubble,
            .user-message-bubble {
              max-width: 85%;
            }
          }
        }
      }

      .ai-input-area {
        padding: 12px 16px;
      }
    }
  }

  .ai-trigger-btn {
    bottom: 15px;
    right: 15px;
    padding: 10px 16px;
    font-size: 13px;
    z-index: 1500; // 确保在移动端也显示在最上层

    i {
      font-size: 16px;
    }
  }
}

.ai-assistant-sidebar {
  position: fixed;
  top: 0;
  right: 0;
  width: 350px;
  height: 100vh;
  background: #fff;
  box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1);
  transform: translateX(100%);
  transition: transform 0.3s ease;
  z-index: 2000; // 提高z-index，确保在导航栏之上
  display: flex;
  flex-direction: column;

  &.show {
    transform: translateX(0);
  }

  .ai-sidebar-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    padding: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #fff;
    // 添加顶部内边距，避免被导航栏遮挡
    // 导航栏64px + TagsView 34px = 98px
    padding-top: calc(16px + 98px);

    .ai-header-info {
      display: flex;
      align-items: center;
      gap: 12px;

      .ai-avatar {
        width: 32px;
        height: 32px;
        border-radius: 50%;
        border: 2px solid #fff;
        flex-shrink: 0;
      }

      .ai-info {
        h4 {
          margin: 0;
          font-size: 16px;
          color: #fff;
          font-weight: 600;
        }

        .ai-status {
          padding: 2px 8px;
          border-radius: 12px;
          font-size: 11px;
          background: rgba(255, 255, 255, 0.2);
          color: #fff;

          &.online {
            background: rgba(103, 194, 58, 0.8);
          }
        }
      }
    }

    .ai-header-actions {
      display: flex;
      align-items: center;
      gap: 8px;

      .clear-btn {
        background: none;
        border: none;
        font-size: 16px;
        color: #fff;
        padding: 4px;
        border-radius: 4px;
        cursor: pointer;
        transition: background-color 0.2s;

        &:hover {
          background: rgba(255, 255, 255, 0.2);
          color: #fff;
        }

        &:disabled {
          opacity: 0.5;
          cursor: not-allowed;
        }
      }

      .close-btn {
        background: none;
        border: none;
        font-size: 18px;
        color: #fff;
        padding: 4px;
        border-radius: 4px;
        cursor: pointer;
        transition: background-color 0.2s;

        &:hover {
          background: rgba(255, 255, 255, 0.2);
          color: #fff;
        }
      }
    }
  }

  .ai-chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    // 调整高度，为顶部导航栏和TagsView留出空间
    height: calc(100vh - 98px);

    .ai-messages {
      flex: 1;
      padding: 16px;
      overflow-y: auto;

      &::-webkit-scrollbar {
        width: 4px;
      }

      &::-webkit-scrollbar-track {
        background: #f1f1f1;
      }

      &::-webkit-scrollbar-thumb {
        background: #c1c1c1;
        border-radius: 2px;
      }

      .ai-message-item {
        margin-bottom: 16px;

        .ai-message-content {
          display: flex;
          align-items: flex-start;
          gap: 8px;

          .ai-avatar-small {
            width: 28px;
            height: 28px;
            border-radius: 50%;
            border: 2px solid #409eff;
            flex-shrink: 0;

            img {
              width: 100%;
              height: 100%;
              border-radius: 50%;
              object-fit: cover;
            }
          }

          .ai-message-bubble {
            max-width: 80%;

            .ai-message-text {
              background: #f0f9ff;
              padding: 10px 12px;
              border-radius: 12px;
              font-size: 13px;
              line-height: 1.4;
              color: #303133;
              word-wrap: break-word;
              border-left: 3px solid #409eff;

              ::v-deep {
                strong {
                  font-weight: 600;
                }

                em {
                  font-style: italic;
                }

                code {
                  background: #e1f5fe;
                  padding: 2px 4px;
                  border-radius: 3px;
                  font-family: "Courier New", monospace;
                }
              }
            }

            .ai-message-time {
              font-size: 11px;
              color: #909399;
              margin-top: 4px;
              margin-left: 4px;
            }
          }
        }

        &.user-message {
          .user-message-content {
            display: flex;
            align-items: flex-start;
            gap: 8px;
            justify-content: flex-end;

            .user-message-bubble {
              max-width: 80%;

              .user-message-text {
                background: #e8f5e8;
                padding: 10px 12px;
                border-radius: 12px;
                font-size: 13px;
                line-height: 1.4;
                color: #303133;
                word-wrap: break-word;
                border-left: 3px solid #67c23a;
                text-align: right;
              }

              .user-message-time {
                font-size: 11px;
                color: #909399;
                margin-top: 4px;
                margin-right: 4px;
                text-align: right;
              }
            }

            .user-avatar-small {
              width: 28px;
              height: 28px;
              border-radius: 50%;
              border: 2px solid #67c23a;
              flex-shrink: 0;

              .avatar-container {
                position: relative;

                img {
                  width: 100%;
                  height: 100%;
                  border-radius: 50%;
                  object-fit: cover;
                }

                .online-indicator {
                  position: absolute;
                  top: 2px;
                  right: 2px;
                  width: 10px;
                  height: 10px;
                  border-radius: 50%;
                  background: #67c23a;
                  border: 2px solid #fff;
                }
              }
            }
          }
        }
      }
    }

    .ai-input-area {
      background: #fff;
      padding: 16px;
      border-top: 1px solid #e4e7ed;

      .ai-input-actions {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-top: 8px;

        .tip {
          font-size: 11px;
          color: #909399;
        }
      }
    }
  }
}

.ai-trigger-btn {
  position: fixed;
  bottom: 20px;
  right: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #fff;
  padding: 12px 20px;
  border-radius: 25px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  cursor: pointer;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
  transition: all 0.3s ease;
  z-index: 1500;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
  }

  i {
    font-size: 18px;
  }

  span {
    font-weight: 500;
  }
}

.typing-indicator {
  display: flex;
  gap: 4px;
  align-items: center;

  span {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #409eff;
    animation: typing 1.4s infinite ease-in-out;

    &:nth-child(1) {
      animation-delay: -0.32s;
    }
    &:nth-child(2) {
      animation-delay: -0.16s;
    }
  }
}

@keyframes typing {
  0%,
  80%,
  100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

// 用户信息对话框样式
.user-info-dialog {
  text-align: center;
  padding: 20px 0;

  .user-avatar-large {
    position: relative;
    display: inline-block;
    margin-bottom: 20px;

    img {
      width: 80px;
      height: 80px;
      border-radius: 50%;
      border: 3px solid #67c23a;
      object-fit: cover;
      background: #f0f0f0;
    }

    .online-indicator-large {
      position: absolute;
      top: 5px;
      right: 5px;
      width: 16px;
      height: 16px;
      border-radius: 50%;
      background: #67c23a;
      border: 3px solid #fff;
    }
  }

  .user-details {
    .user-name {
      margin: 0 0 8px 0;
      font-size: 18px;
      font-weight: 600;
      color: #303133;
    }

    .user-nickname {
      margin: 0 0 12px 0;
      font-size: 14px;
      color: #909399;
    }

    .user-status {
      margin: 0 0 8px 0;
      font-size: 14px;
      color: #67c23a;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 6px;

      i {
        font-size: 16px;
      }
    }

    .user-join-time {
      margin: 0;
      font-size: 12px;
      color: #909399;
    }
  }
}
</style>
